package org.xiaohanghu.starter;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * @author xiaohanghu
 */
public class JavaCommandUtils {

	/**
	 * 启动一个jvm
	 * */
	public static void startJvm(List<String> options,
			Map<String, String> sysProps, String classPath, String mainClass,
			List<String> args) throws IOException, InterruptedException {
		String cmd = buildCommandLine(options, sysProps, classPath, mainClass,
				args);
		runCommand(cmd);
	}

	public static void runCommand(String cmd) throws IOException,
			InterruptedException {
		final Process process = Runtime.getRuntime().exec(cmd);
		Runtime.getRuntime().addShutdownHook(new Thread() {
			public void run() {
				// Config.debug("Destroying " + process);
				process.destroy();
			}
		});
		copyInThread(process.getErrorStream(), System.err);
		copyInThread(process.getInputStream(), System.out);
		copyInThread(System.in, process.getOutputStream());
		// monitor.setProcess(process);
		process.waitFor();
	}

	private static void copyInThread(final InputStream in,
			final OutputStream out) {
		new Thread(new Runnable() {
			public void run() {
				try {
					byte[] buf = new byte[1024];
					int len = in.read(buf);
					while (len > 0) {
						out.write(buf, 0, len);
						len = in.read(buf);
					}
				} catch (IOException e) {
					// e.printStackTrace();
				}
			}

		}).start();
	}

	public static String buildCommandLine(List<String> options,
			Map<String, String> systemPropertys, String classPath,
			String mainClass, List<String> args) throws IOException {
		StringBuilder cmd = new StringBuilder();
		/** java */
		cmd.append(findJavaBin());

		/** options */
		if (null != options) {
			for (String option : options) {
				cmd.append(' ').append(option);
			}
		}
		if (null != systemPropertys) {
			for (Entry<String, String> entry : systemPropertys.entrySet()) {
				String value = entry.getValue();
				if (value != null) {
					cmd.append(" -D").append(entry.getKey());
					// cmd.append('=').append('"').append(value).append('"');
					cmd.append('=').append(value);
				}
			}
		}

		/** 加载当前的java资源 */
		if (StringUtils.isNotBlank(classPath)) {
			cmd.append(" -cp ").append(classPath);
			// cmd.append('\"');
		}

		cmd.append(' ').append(mainClass);

		if (null != args) {
			for (String arg : args) {
				// cmd.append(' ').append('"').append(arg).append('"');
				cmd.append(' ').append(arg);
			}
		}

		return cmd.toString();
	}

	public static String findJavaBin() {
		File javaHome = new File(System.getProperty("java.home"));
		if (!javaHome.exists()) {
			return null;
		}

		File javabin = findExecutable(javaHome, "bin/java");
		if (javabin != null) {
			return javabin.getAbsolutePath();
		}

		javabin = findExecutable(javaHome, "bin/java.exe");
		if (javabin != null) {
			return javabin.getAbsolutePath();
		}

		return "java";
	}

	private static File findExecutable(File root, String path) {
		String npath = path.replace('/', File.separatorChar);
		File exe = new File(root, npath);
		if (!exe.exists()) {
			return null;
		}
		return exe;
	}

}
